package edu.uci.ics.multicast.host;

/**
 * reference: http://darksleep.com/player/SocketExample/
 */

import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.LinkedList;
import java.util.List;

import edu.uci.ics.multicast.ThreadReceiveForwardStreaming;


public class MulticastPeer {

	private String serverHostname = null;
	private int serverPort = 0;
	
	private List<Socket> listSocketChildren = new LinkedList<Socket>();
	
	public MulticastPeer(String serverHostname, int serverPort){
		this.serverHostname =  serverHostname;
		this.serverPort = serverPort;
	}

	/**
	 * 	Figure out which father to connect to (request to rendezvous)
	 * 
	 * @return father hostName
	 * @throws SocketException
	 * @throws IOException
	 * @throws ClassNotFoundException 
	 */
	private String requestOneFather() throws SocketException, IOException, ClassNotFoundException {
		Socket sock = new Socket(serverHostname, serverPort);
		System.err.println("Connection openned with "+serverHostname+" port "+serverPort);
		ObjectInputStream sockInput = new ObjectInputStream(sock.getInputStream());
        String fatherHostName = (String) sockInput.readObject();
		sock.close();
		return fatherHostName;
	}

	private void receiveForwardStreaming(String fatherHostName) {
		ThreadReceiveForwardStreaming receivingStreaming = new ThreadReceiveForwardStreaming(fatherHostName,listSocketChildren);
		receivingStreaming.start();
	}
	
	private void addingNewChild() throws IOException {
		Runnable childTask = new Runnable(){
			public void run() {
				ServerSocket serverSock;
				try {
					serverSock = new ServerSocket(Source.STREAMING_PORT);
					while (true) {
						Socket sock = serverSock.accept();
						listSocketChildren.add(sock);
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		};
		new Thread(childTask).start();
	}
	
	public static void main(String argv[]) {
		MulticastPeer peer = new MulticastPeer(argv[0], Rendezvous.ADMISSION_PORT);
		try {
			// peer request a father
			String fatherHostName = peer.requestOneFather();
			
			// peer start to receive streaming
			peer.receiveForwardStreaming(fatherHostName);
		
			// wait for a request and add new child		
			peer.addingNewChild();
			
		} catch (SocketException e) {
			e.printStackTrace(System.err);
		} catch (IOException e) {
			e.printStackTrace(System.err);
		} catch (ClassNotFoundException e) {
			e.printStackTrace(System.err);
		}
	}

}
